import logging
from typing import List, Tuple, Type, Dict, Any, Optional, Union
import pandas as pd
import time

from qtorch.di.container import DIContainer
from qtorch.events.bus import EventBus
from qtorch.core.config import ConfigManager
from qtorch.core.visualizer import Visualizer
from qtorch.core.qvisualizer import QVisualizer

# 尝试导入GPU相关模块
try:
    from qtorch.utils.device_utils import (
        get_device, is_gpu_available, get_device_manager, get_autocast_context
    )
    import torch
    GPU_AVAILABLE = True
except ImportError:
    GPU_AVAILABLE = False
    logging.warning("GPU加速模块未安装，将使用CPU计算")


class QResult:
    """回测结果包装类，提供简便的结果访问和可视化功能"""
    
    def __init__(self, engine, data: pd.DataFrame, metrics: Dict[str, float], 
                trades=None, perf_stats: Dict[str, Any] = None):
        """
        初始化回测结果对象
        
        参数:
            engine: 引擎实例
            data: 回测数据
            metrics: 性能指标
            trades: 交易记录
            perf_stats: GPU性能统计（如果使用GPU加速）
        """
        self.engine = engine
        self.data = data
        self.metrics = metrics
        self.trades = trades
        self.perf_stats = perf_stats or {}
        self._visualizer = QVisualizer()
        
    def plot(self, output_dir: str = "./output", save: bool = True, 
            show_dashboard: bool = True, show_gpu_stats: bool = True):
        """
        绘制回测结果图表，使用增强的可视化功能
        
        参数:
            output_dir: 输出目录
            save: 是否保存图表文件
            show_dashboard: 是否显示综合仪表盘
            show_gpu_stats: 是否显示GPU性能统计
            
        返回:
            self: 支持链式调用
        """
        # 设置输出目录
        self._visualizer.output_dir = output_dir
        
        if show_dashboard:
            # 生成综合仪表盘
            self._visualizer.plot_strategy_dashboard(
                data=self.data,
                trades=self.trades,
                metrics=self.metrics,
                save_path=f"{output_dir}/dashboard.png" if save else None
            )
        
        # 绘制收益曲线
        self._visualizer.plot_equity_curve(
            data=self.data,
            title="策略收益曲线",
            save_path=f"{output_dir}/equity_curve.png" if save else None
        )
        
        # 绘制回撤分析
        self._visualizer.plot_drawdown(
            data=self.data,
            title="策略回撤分析",
            save_path=f"{output_dir}/drawdown.png" if save else None
        )
        
        # 如果有日期索引，绘制月度收益热力图
        if isinstance(self.data.index, pd.DatetimeIndex):
            self._visualizer.plot_monthly_returns(
                data=self.data,
                title="月度收益热力图",
                save_path=f"{output_dir}/monthly_returns.png" if save else None
            )
            
        # 如果有交易记录，绘制交易分析
        if self.trades:
            self._visualizer.plot_trade_analysis(
                trades=self.trades,
                title="交易分析",
                save_path=f"{output_dir}/trade_analysis.png" if save else None
            )
            
        # 调用原始引擎的报告生成
        if hasattr(self.engine, 'generate_report') and save:
            try:
                self.engine.generate_report(output_dir=output_dir)
            except Exception as e:
                logging.warning(f"原始报告生成失败: {str(e)}")
                
        # 生成HTML报告
        if save:
            self._visualizer.generate_html_report(
                data=self.data,
                trades=self.trades,
                metrics=self.metrics,
                strategy_name="QTorch策略回测",
                output_path=f"{output_dir}/enhanced_report.html"
            )
        
        # 绘制GPU性能统计（如果有）
        if show_gpu_stats and self.perf_stats and hasattr(self._visualizer, 'plot_figure'):
            try:
                self._plot_gpu_stats(output_dir, save)
            except Exception as e:
                logging.warning(f"GPU性能统计绘制失败: {str(e)}")
                
        if save:
            logging.info(f"回测图表已保存至: {output_dir}")
            
        return self
    
    def _plot_gpu_stats(self, output_dir: str, save: bool):
        """绘制GPU性能统计图表"""
        if not self.perf_stats:
            return
            
        import matplotlib.pyplot as plt
        import numpy as np
        
        # 检查是否有GPU操作
        gpu_ops = self.perf_stats.get('gpu_ops', 0)
        if gpu_ops <= 0:
            return
            
        # 绘制GPU/CPU操作对比
        cpu_ops = self.perf_stats.get('cpu_ops', 0)
        gpu_time = self.perf_stats.get('gpu_time', 0)
        cpu_time = self.perf_stats.get('cpu_time', 0)
        
        fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
        
        # 操作数量对比
        labels = ['GPU操作', 'CPU操作']
        values = [gpu_ops, cpu_ops]
        
        ax1.pie(values, labels=labels, autopct='%1.1f%%', 
               startangle=90, colors=['green', 'blue'])
        ax1.set_title('GPU vs CPU 操作比例')
        
        # 时间分布
        ax2.pie([gpu_time, cpu_time], labels=labels, autopct='%1.1f%%', 
               startangle=90, colors=['green', 'blue'])
        ax2.set_title('GPU vs CPU 时间比例')
        
        plt.tight_layout()
        
        if save:
            plt.savefig(f"{output_dir}/gpu_stats.png")
            
        # 如果有加速比数据，绘制加速比图表
        if 'speedup_metrics' in self.perf_stats and self.perf_stats['speedup_metrics']:
            speedup_data = self.perf_stats['speedup_metrics']
            
            fig, ax = plt.subplots(figsize=(10, 5))
            operations = list(speedup_data.keys())
            speedups = list(speedup_data.values())
            
            y_pos = np.arange(len(operations))
            ax.barh(y_pos, speedups, align='center')
            ax.set_yticks(y_pos)
            ax.set_yticklabels(operations)
            ax.invert_yaxis()  # 最高值在顶部
            ax.set_xlabel('加速比 (×)')
            ax.set_title('各操作GPU加速比')
            
            for i, v in enumerate(speedups):
                ax.text(v + 0.1, i, f"{v:.2f}×", va='center')
            
            plt.tight_layout()
            
            if save:
                plt.savefig(f"{output_dir}/speedup_metrics.png")
    
    def print_performance_stats(self):
        """打印GPU性能统计信息"""
        if not self.perf_stats:
            print("未启用GPU加速或无GPU性能统计信息")
            return self
            
        print("\n===== GPU性能统计 =====")
        print(f"设备: {self.perf_stats.get('device', 'unknown')}")
        print(f"GPU操作次数: {self.perf_stats.get('gpu_ops', 0)}")
        print(f"CPU操作次数: {self.perf_stats.get('cpu_ops', 0)}")
        
        gpu_time = self.perf_stats.get('gpu_time', 0)
        cpu_time = self.perf_stats.get('cpu_time', 0)
        total_time = gpu_time + cpu_time
        
        if total_time > 0:
            print(f"GPU时间: {gpu_time:.2f}秒 ({gpu_time/total_time*100:.1f}%)")
            print(f"CPU时间: {cpu_time:.2f}秒 ({cpu_time/total_time*100:.1f}%)")
        
        if 'speedup_metrics' in self.perf_stats and self.perf_stats['speedup_metrics']:
            print("\n各操作的加速比:")
            for op, sp in self.perf_stats['speedup_metrics'].items():
                print(f"  - {op}: {sp:.2f}x")
                
        if 'tensor_converts' in self.perf_stats:
            print(f"\n张量转换次数: {self.perf_stats['tensor_converts']}")
            print(f"GPU计算次数: {self.perf_stats.get('gpu_calculations', 0)}")
            
        return self
        
    def summary(self):
        """打印回测指标摘要"""
        print("===== 回测结果摘要 =====")
        
        # 关键指标
        key_metrics = ["总收益率", "年化收益率", "最大回撤", "夏普比率", "索提诺比率", 
                      "胜率", "盈亏比", "交易次数"]
                      
        # 打印关键指标
        for key in key_metrics:
            if key in self.metrics:
                value = self.metrics[key]
                if isinstance(value, float):
                    if key in ["总收益率", "年化收益率", "最大回撤", "胜率"]:
                        print(f"{key}: {value:.2%}")
                    else:
                        print(f"{key}: {value:.4f}")
                else:
                    print(f"{key}: {value}")
        
        # 添加性能统计信息（如果使用了GPU）
        if self.perf_stats and self.perf_stats.get('gpu_ops', 0) > 0:
            gpu_time = self.perf_stats.get('gpu_time', 0)
            cpu_time = self.perf_stats.get('cpu_time', 0)
            print(f"\n计算加速: {'使用GPU' if gpu_time > 0 else '使用CPU'}")
            
            # 如果有计算加速比，显示加速比
            if 'speedup_metrics' in self.perf_stats and self.perf_stats['speedup_metrics']:
                avg_speedup = sum(self.perf_stats['speedup_metrics'].values()) / len(self.perf_stats['speedup_metrics'])
                print(f"平均加速比: {avg_speedup:.2f}x")
        
        return self


class QEngine:
    """QTorch框架统一入口类，提供类似Backtrader的流畅API，自动支持GPU加速"""
    
    def __init__(self, force_cpu: bool = False):
        """
        初始化QEngine
        
        参数:
            force_cpu: 是否强制使用CPU，即使有GPU可用
        """
        self._di = DIContainer()
        self._bus = EventBus()
        self._config = ConfigManager()
        self._data_sources = []
        self._strategy = None
        self._strategy_params = {}
        self._cash = 1000000.0
        # 默认费率配置，按资产类型区分
        self._commissions = {
            'stock': 0.0003,    # 股票默认佣金
            'futures': 0.00005, # 期货默认佣金
            'option': 0.0005,   # 期权默认佣金
            'bond': 0.0001,     # 债券默认佣金
            'crypto': 0.001,    # 加密货币默认佣金
            'default': 0.0003   # 其他资产类型默认佣金
        }
        # 保证金比例，按资产类型区分
        self._margin_ratios = {
            'stock': 0.12,      # 股票默认保证金比例
            'futures': 0.08,    # 期货默认保证金比例
            'option': 1.0,      # 期权默认保证金比例(全额)
            'default': 0.12     # 其他资产类型默认保证金比例
        }
        # 合约乘数，按资产类型区分
        self._contract_multipliers = {
            'stock': 1.0,        # 股票默认乘数
            'futures': 300.0,    # 期货默认乘数(如IF)
            'option': 10000.0,   # 期权默认乘数
            'default': 1.0       # 其他资产类型默认合约乘数
        }
        self._allow_short = True
        self._config_path = None
        self._trades = []  # 记录交易历史
        self._asset_types = {}  # 存储每个标的对应的资产类型
        
        # GPU加速相关设置
        self._force_cpu = force_cpu
        self._use_gpu = False  # 是否启用GPU加速，将在run()中根据条件自动设置
        self._mixed_precision = True  # 是否使用混合精度计算
        self._gpu_batch_size = 1024  # GPU批处理大小
        self._auto_use_gpu_threshold = 10000  # 自动使用GPU的数据量阈值
        self._enable_performance_logging = True  # 是否启用性能日志
        self._benchmark_mode = False  # 是否启用性能对比模式
        
        # 检测GPU可用性
        if GPU_AVAILABLE and not force_cpu and is_gpu_available():
            device = get_device()
            logging.info(f"QEngine已初始化，检测到可用设备: {device}")
            self._device = device
            self._use_gpu = True
        else:
            if force_cpu:
                logging.info("QEngine已初始化，强制使用CPU")
            elif not GPU_AVAILABLE:
                logging.info("QEngine已初始化，GPU加速模块未安装，使用CPU")
            else:
                logging.info("QEngine已初始化，未检测到GPU设备，使用CPU")
            self._device = None
            self._use_gpu = False
        
    def add_data(self, symbol: str, start_date: str = None, end_date: str = None,
                 asset_type: str = 'stock') -> 'QEngine':
        """
        添加回测数据
        
        参数:
            symbol: 资产代码
            start_date: 开始日期 (格式: YYYY-MM-DD)
            end_date: 结束日期 (格式: YYYY-MM-DD)
            asset_type: 资产类型，可选值：'stock'(股票), 'futures'(期货), 'option'(期权), 'bond'(债券), 'crypto'(加密货币)
        
        返回:
            self: 支持链式调用
        """
        self._data_sources.append((symbol, start_date, end_date, asset_type))
        self._asset_types[symbol] = asset_type
        return self
        
    def add_strategy(self, strategy_class: Type, **params) -> 'QEngine':
        """
        添加交易策略
        
        参数:
            strategy_class: 策略类
            **params: 策略参数
            
        返回:
            self: 支持链式调用
        """
        self._strategy = strategy_class
        self._strategy_params = params
        return self
        
    def set_cash(self, amount: float) -> 'QEngine':
        """
        设置初始资金
        
        参数:
            amount: 初始资金数额
            
        返回:
            self: 支持链式调用
        """
        self._cash = amount
        return self
        
    def set_commission(self, commission: float, asset_type: str = 'default') -> 'QEngine':
        """
        设置交易佣金
        
        参数:
            commission: 交易佣金比例
            asset_type: 资产类型，可选值：'stock'(股票), 'futures'(期货), 'option'(期权), 'bond'(债券), 'crypto'(加密货币), 'default'(默认)
            
        返回:
            self: 支持链式调用
        """
        self._commissions[asset_type] = commission
        return self
        
    def set_margin(self, margin_ratio: float, asset_type: str = 'default') -> 'QEngine':
        """
        设置保证金比例
        
        参数:
            margin_ratio: 保证金比例
            asset_type: 资产类型，可选值：'stock'(股票), 'futures'(期货), 'option'(期权), 'default'(默认)
            
        返回:
            self: 支持链式调用
        """
        self._margin_ratios[asset_type] = margin_ratio
        return self
        
    def set_contract_multiplier(self, multiplier: float, asset_type: str = 'default') -> 'QEngine':
        """
        设置合约乘数
        
        参数:
            multiplier: 合约乘数
            asset_type: 资产类型，可选值：'stock'(股票), 'futures'(期货), 'option'(期权), 'default'(默认)
            
        返回:
            self: 支持链式调用
        """
        self._contract_multipliers[asset_type] = multiplier
        return self
        
    def allow_short(self, allow: bool = True) -> 'QEngine':
        """
        设置是否允许做空
        
        参数:
            allow: 是否允许做空
            
        返回:
            self: 支持链式调用
        """
        self._allow_short = allow
        return self
        
    def set_config(self, config_path: str) -> 'QEngine':
        """
        设置配置文件路径
        
        参数:
            config_path: 配置文件路径
            
        返回:
            self: 支持链式调用
        """
        self._config_path = config_path
        return self
    
    # GPU加速相关方法
    def set_use_gpu(self, use_gpu: bool = True) -> 'QEngine':
        """
        设置是否使用GPU加速
        
        参数:
            use_gpu: 是否使用GPU
            
        返回:
            self: 支持链式调用
        """
        if use_gpu and not GPU_AVAILABLE:
            logging.warning("GPU加速模块未安装，无法启用GPU加速")
            return self
            
        if use_gpu and not is_gpu_available():
            logging.warning("系统上没有检测到可用的GPU，无法启用GPU加速")
            return self
            
        self._use_gpu = use_gpu
        self._force_cpu = not use_gpu
        return self
    
    def set_mixed_precision(self, enabled: bool = True) -> 'QEngine':
        """
        设置是否使用混合精度计算
        
        参数:
            enabled: 是否启用混合精度
            
        返回:
            self: 支持链式调用
        """
        self._mixed_precision = enabled
        return self
    
    def set_gpu_batch_size(self, batch_size: int) -> 'QEngine':
        """
        设置GPU批处理大小
        
        参数:
            batch_size: 批处理大小
            
        返回:
            self: 支持链式调用
        """
        self._gpu_batch_size = batch_size
        return self
    
    def set_auto_use_gpu_threshold(self, threshold: int) -> 'QEngine':
        """
        设置自动使用GPU的数据量阈值
        
        参数:
            threshold: 数据量阈值，超过此值时自动使用GPU
            
        返回:
            self: 支持链式调用
        """
        self._auto_use_gpu_threshold = threshold
        return self
    
    def enable_benchmark_mode(self, enabled: bool = True) -> 'QEngine':
        """
        启用性能对比模式，同时用CPU和GPU计算并比较性能
        
        参数:
            enabled: 是否启用性能对比模式
            
        返回:
            self: 支持链式调用
        """
        self._benchmark_mode = enabled
        return self
        
    def run(self) -> QResult:
        """
        运行回测，自动使用GPU加速（如可用）
        
        返回:
            QResult: 回测结果对象
        """
        run_start_time = time.time()
        
        try:
            # 创建配置
            if self._config_path:
                config = ConfigManager(self._config_path)
            else:
                config = ConfigManager()
                
            # 更新引擎配置
            config.update_config("engine", "initial_capital", self._cash)
            
            # 更新多资产类型支持的配置
            config.update_config("engine", "commissions", self._commissions)
            config.update_config("engine", "margin_ratios", self._margin_ratios)
            config.update_config("engine", "contract_multipliers", self._contract_multipliers)
            config.update_config("engine", "asset_types", self._asset_types)
            config.update_config("engine", "allow_short", self._allow_short)
            
            # 更新GPU相关配置
            config.update_config("engine", "force_cpu", self._force_cpu)
            config.update_config("engine", "use_gpu", self._use_gpu)
            config.update_config("engine", "mixed_precision", self._mixed_precision)
            config.update_config("engine", "gpu_batch_size", self._gpu_batch_size)
            config.update_config("engine", "auto_use_gpu_threshold", self._auto_use_gpu_threshold)
            
            # 性能对比配置
            config.update_config("debug", "compare_gpu_cpu", self._benchmark_mode)
            
            # 确保至少有一个数据源
            if not self._data_sources:
                raise ValueError("请添加至少一个数据源")
            
            # 设置开始和结束日期
            if len(self._data_sources[0]) >= 3:
                start_date = self._data_sources[0][1]
                end_date = self._data_sources[0][2]
                if start_date:
                    config.update_config("engine", "start_date", start_date)
                if end_date:
                    config.update_config("engine", "end_date", end_date)
                    
            # 设置交易标的
            symbols = [data_source[0] for data_source in self._data_sources]
            config.update_config("engine", "symbols", symbols)
            
            # 按资产类型分组交易标的
            asset_type_symbols = {}
            for symbol, start_date, end_date, asset_type in self._data_sources:
                if asset_type not in asset_type_symbols:
                    asset_type_symbols[asset_type] = []
                asset_type_symbols[asset_type].append(symbol)
            
            config.update_config("engine", "asset_type_symbols", asset_type_symbols)
            
            # 注册组件
            self._setup_components(config)
            
            # 记录交易历史
            self._setup_trade_history()
            
            # 创建引擎实例（根据条件选择合适的引擎类）
            if self._use_gpu and GPU_AVAILABLE:
                try:
                    # 导入GPU引擎
                    from qtorch.core.gpu_engine import GPUEngine
                    engine = GPUEngine(self._di, self._bus, None)
                    logging.info("使用GPU加速引擎运行回测")
                except ImportError:
                    from qtorch.core.engine import Engine
                    engine = Engine(self._di, self._bus, None)
                    logging.warning("GPU引擎导入失败，降级为标准引擎")
            else:
                from qtorch.core.engine import Engine
                engine = Engine(self._di, self._bus, None)
                logging.info("使用标准引擎运行回测")
            
            # 运行回测，检查是否需要按资产类型分组处理
            if len(asset_type_symbols) > 1:
                result, metrics = self._run_multi_asset(engine, asset_type_symbols)
            else:
                # 单一资产类型
                result = engine.run(symbols)
                metrics = engine.calculate_metrics(result)
            
            # 获取性能统计（如果使用了GPU引擎）
            perf_stats = {}
            if hasattr(engine, 'get_performance_stats'):
                perf_stats = engine.get_performance_stats()
            
            # 记录性能信息
            total_time = time.time() - run_start_time
            if perf_stats and self._enable_performance_logging:
                logging.info(f"回测完成，总耗时: {total_time:.2f}秒")
                if perf_stats.get('gpu_ops', 0) > 0:
                    gpu_time = perf_stats.get('gpu_time', 0)
                    cpu_time = perf_stats.get('cpu_time', 0)
                    gpu_percentage = (gpu_time / total_time) * 100 if total_time > 0 else 0
                    
                    logging.info(f"GPU操作: {perf_stats.get('gpu_ops', 0)}次，" 
                                f"CPU操作: {perf_stats.get('cpu_ops', 0)}次")
                    logging.info(f"GPU时间占比: {gpu_percentage:.1f}% ({gpu_time:.2f}秒)")
                    
                    # 记录加速比
                    if 'speedup_metrics' in perf_stats and perf_stats['speedup_metrics']:
                        logging.info("各操作的加速比:")
                        for op, sp in perf_stats['speedup_metrics'].items():
                            logging.info(f"  - {op}: {sp:.2f}x")
            
            # 返回增强的结果对象
            return QResult(engine, result, metrics, trades=self._trades, perf_stats=perf_stats)
            
        except Exception as e:
            logging.error(f"回测执行失败: {str(e)}", exc_info=True)
            raise
    
    def _setup_components(self, config):
        """设置组件：数据提供者、策略、风险管理等"""
        # 注册数据提供者
        cache_dir = config.get("data", "cache_dir", "./data_cache")
        cache_ttl = config.get("data", "cache_ttl", 86400)
        
        # 使用多资产数据获取器
        try:
            from qtorch.data.multi_asset_fetcher import MultiAssetFetcher
            self._di.register_data_provider(MultiAssetFetcher(
                cache_dir=cache_dir,
                cache_ttl=cache_ttl
            ))
            logging.info("成功注册多资产数据获取器")
        except ImportError:
            # 降级为仅股票数据获取器
            from qtorch.data.aksharestockerfetcher import AKShareStockFetcher
            logging.warning("未找到多资产数据获取器，降级为股票数据获取器")
            self._di.register_data_provider(AKShareStockFetcher(
                cache_dir=cache_dir,
                cache_ttl=cache_ttl
            ))
        
        # 注册事件总线
        try:
            from qtorch.events.enhanced_bus import EnhancedEventBus
            enhanced_bus = EnhancedEventBus()
            self._bus = enhanced_bus
            logging.info("成功注册增强型事件总线")
        except ImportError:
            logging.warning("未找到增强型事件总线，使用标准事件总线")
            
        # 注册策略
        if not self._strategy:
            raise ValueError("请添加策略")
        strategy = self._strategy(**self._strategy_params)
        self._di.register_strategy(strategy)
        
        # 注册风险管理
        from qtorch.core.riskmanager import RiskManager
        risk_config = config.get_section("risk") or {}
        self._di.register_risk_manager(RiskManager(
            max_position=risk_config.get("max_position", 0.1),
            max_loss=risk_config.get("max_loss", 0.05)
        ))
    
    def _setup_trade_history(self):
        """设置交易历史记录"""
        self._trades = []
        
        # 导入所需模块
        from datetime import datetime
        from qtorch.events.bus import SignalEvent
        
        # 捕获信号事件
        def on_signal_handler(event):
            # 记录交易
            if hasattr(event, 'signals'):
                timestamp = event.timestamp if hasattr(event, 'timestamp') else datetime.now()
                
                # 处理增强型多资产信号事件
                if hasattr(event, '__class__') and event.__class__.__name__ == 'MultiAssetSignalEvent':
                    for symbol, signal_info in event.signals.items():
                        signal_value = signal_info.get('value', 0)
                        asset_type = signal_info.get('asset_type', 'stock')
                        
                        if signal_value != 0:  # 非0信号意味着有交易
                            trade = {
                                'timestamp': timestamp,
                                'symbol': symbol,
                                'signal': signal_value,
                                'asset_type': asset_type,
                                'strategy': event.strategy if hasattr(event, 'strategy') else 'unknown'
                            }
                            self._trades.append(trade)
                # 处理标准信号事件
                elif hasattr(event, 'signals') and isinstance(event.signals, dict):
                    for symbol, signal in event.signals.items():
                        if signal != 0:  # 非0信号意味着有交易
                            asset_type = self._asset_types.get(symbol, 'stock')
                            trade = {
                                'timestamp': timestamp,
                                'symbol': symbol,
                                'signal': signal,
                                'asset_type': asset_type,
                                'strategy': event.strategy if hasattr(event, 'strategy') else 'unknown'
                            }
                            self._trades.append(trade)
        
        # 注册信号事件处理器
        self._bus.subscribe(SignalEvent, on_signal_handler)
        
        # 如果使用增强型事件总线，注册多资产信号事件处理器
        if hasattr(self._bus, '__class__') and self._bus.__class__.__name__ == 'EnhancedEventBus':
            try:
                from qtorch.events.enhanced_bus import MultiAssetSignalEvent
                self._bus.subscribe(MultiAssetSignalEvent, on_signal_handler)
            except ImportError:
                pass
    
    def _run_multi_asset(self, engine, asset_type_symbols):
        """运行多资产回测"""
        all_results = {}
        all_metrics = {}
        
        # 按资产类型分组处理
        for asset_type, asset_symbols in asset_type_symbols.items():
            logging.info(f"处理 {asset_type} 类型资产: {', '.join(asset_symbols)}")
            
            # 每种资产类型使用对应的交易费率和参数
            engine._commission = self._commissions.get(asset_type, self._commissions.get('default'))
            engine._margin_ratio = self._margin_ratios.get(asset_type, self._margin_ratios.get('default'))
            engine._contract_multiplier = self._contract_multipliers.get(asset_type, self._contract_multipliers.get('default'))
            
            # 运行该资产类型的回测
            asset_result = engine.run(asset_symbols)
            
            # 计算该资产类型的指标
            asset_metrics = engine.calculate_metrics(asset_result)
            
            # 存储结果
            all_results[asset_type] = asset_result
            all_metrics[asset_type] = asset_metrics
        
        # 合并所有结果
        import pandas as pd
        # 多资产结果合并
        combined_results = pd.concat([df for df in all_results.values()], axis=1, join='outer')
        
        # 针对所有资产的组合指标计算
        metrics = engine.calculate_metrics(combined_results)
        
        # 添加各资产类型的单独指标
        for asset_type, asset_metrics in all_metrics.items():
            for key, value in asset_metrics.items():
                metrics[f"{asset_type}_{key}"] = value
        
        return combined_results, metrics